1.1.2Updated a month ago
import { PageProps } from "$fresh/server.ts";
import moment from "npm:moment";
import { Sort } from "$utils/sort_utils.ts";
import { ExtractFile, ExtractFileVersionHistory } from "@components/package/files/Code.tsx";
import { PackageTab } from "$types/package_tabs.enum.ts";

export default function PackageLayout({ Component, state: { tab, pathname, _package, token_users }}: PageProps<unknown, Viapak.Package.State>) {
  const last_updated = _package.versions.current == _package.versions.latest
    ? _package.last_updated
    : _package.events.filter(e => e.version == _package.versions.current).sort(Sort.Event.Descending)[0].timestamp;

  const file = ExtractFile(pathname, _package);
  const file_version_history = ExtractFileVersionHistory(pathname, _package);

  return (
    <>
      <div class="sticky top-0 w-full bg-base-200 px-6 py-4 z-1">
        <div class="text-lg">
          <a href={`/${_package.namespace}`}>{_package.namespace}</a>
          <span class="cursor-default">
            /
            <a href={`/${_package.namespace}/${_package.name}`}>{_package.name}</a>
          </span>
        </div>
        <div class="mt-4 text-sm opacity-60 tracking-wide flex gap-2">
          <span>{_package.versions.current}</span>

          <span>{_package.events.length > 1 ? 'Updated' : 'Published'} {moment(last_updated).fromNow()}</span>
        </div>
        { _package.tags.length > 0 &&
          <div class="flex gap-2 mt-4">
            { _package.tags.map(tag => (
              <a href={`/tags/${tag}`} class="badge badge-primary badge-soft">{ tag }</a>
            ))}
          </div>
        }
      </div>

      <div role="tablist" class="tabs tabs-border px-4 mt-4 -mb-2">
        <a role="tab" class={`tab ${tab == PackageTab.README ? ' tab-active' : ''}`} href={`${_package.url}`}>Readme</a>
        <a role="tab" class={`tab ${tab == PackageTab.BROWSE ? ' tab-active' : ''}`} href={`${_package.url}?tab=browse`}>Browse</a>
        {/* <a role="tab" class={`tab ${tab == PackageTab.VERSIONS ? ' tab-active' : ''}`} href={`${_package.url}?tab=versions`}>Versions ({_package.versions.all.length})</a> */}
      </div>

      <div class="flex flex-col gap-12 md:flex-row md:gap-4 px-4 justify-start max-w-full">
        <div class="flex flex-col md:grow min-w-0">
          <Component />
        </div>
        <div class="md:w-72 shrink-0">
          <ul class="menu w-full">
            { file && file_version_history && file_version_history.length > 0 && <>
              <li class="menu-title">File Version History</li>
              { file_version_history.sort(Sort.EventVersion.Descending).map(event => {
                const url = event.version == _package.versions.latest
                  ? `/${_package.namespace}/${_package.name}/${file.name}`
                  : `/${_package.namespace}/${_package.name}@${event.version}/${file.name}`;

                const active = _package.versions.current == event.version;

                return (
                  <li>
                    <a href={url} class={`grid-cols-1${active ? ' menu-active' : ''}`}>
                      <div class="flex flex-col">
                        <div class="flex justify-between items-center">
                          <span>
                            { event.version }
                          </span>
                          <span class="text-xs opacity-60 tracking-wide flex">
                            { moment(event.timestamp).fromNow() }
                          </span>
                        </div>
                        { event &&
                          <div class="mt-2 text-xs opacity-60 tracking-wider flex">
                            {_package.namespace}/{_package.name}@{event.version}/{file.name}
                          </div>
                        }
                      </div>
                    </a>
                  </li>
                )
              })}
              <div class="mt-12" />
            </> }


            <li class="menu-title">Package Version History</li>
            { _package.versions.all.sort(Sort.Version.Descending).map(version => {
              const event = _package.events.filter(e => e.version == version).sort(Sort.Event.Descending)[0];

              let url = version == _package.versions.latest
                ? `/${_package.namespace}/${_package.name}`
                : `/${_package.namespace}/${_package.name}@${version}`;

              if(tab !== PackageTab.README) url += `?tab=${tab}`;

              const active = _package.versions.current == version;

              return (
                <li>
                  <a href={url} class={`grid-cols-1${active ? ' menu-active' : ''}`}>
                    <div class="flex flex-col">
                      <div class="flex justify-between items-center">
                        <span>
                          { version }
                        </span>
                        <span class="text-xs opacity-60 tracking-wide flex">
                          { moment(event.timestamp).fromNow() }
                        </span>
                      </div>
                      { event &&
                        <div class="mt-2 text-xs opacity-60 tracking-wider flex">
                          {_package.namespace}/{_package.name}@{version}
                        </div>
                      }
                    </div>
                  </a>
                </li>
              )
            })}


            <li class="menu-title mt-12">Package Events</li>
            { _package.events.sort(Sort.Event.Descending).filter((_, i) => i < 50).map(event => (
              <li>
                <a class="grid-cols-1 pointer-events-none">
                  <div class="flex flex-col">
                    <div class="flex justify-between items-center">
                      <span>
                        { event.event }
                      </span>
                      <span class="text-xs opacity-60 tracking-wide flex">
                        { moment(event.timestamp).fromNow() }
                      </span>
                    </div>
                    <div class="mt-2 text-xs opacity-60 tracking-wider flex">
                      {_package.namespace}/{_package.name}@{event.version}
                    </div>
                    <div class="mt-2 text-sm opacity-80 tracking-wider">
                      {token_users[event.token] !== null ?
                          `@${token_users[event.token]!.username}`
                        :
                          `[invalid user reference]`
                      }
                    </div>
                  </div>
                </a>
              </li>
            ))}
          </ul>
        </div>
      </div>
    </>
  )
}